package com.ebocy.hammer.core.util;

import java.io.InputStream;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.log4j.Logger;

import com.ebocy.hammer.core.constants.GameConstants;
import com.ebocy.hammer.core.db.DAOConstants.DBType;
import com.ebocy.hammer.core.log.EbocyLogManager;

/**
 * 游戏配置信息
 * 
 * @author HouQingrong Jun 13, 2012
 */
public class Config {
	private static Config instance = null;

	private Config() {
	}

	public static Config getInstance() {
		if (instance == null) {
			instance = new Config();
		}
		return instance;
	}

	private static Logger logger = EbocyLogManager.getSystemLogger();
	private final String PROPERTY_FILE_PATH = "properties.properties";
	private final String PORT_FILE_PATH = "port.properties";
	private Properties properties = null;
	private Properties protProperties = null;

	public static short serverPort; // 当前服务器端口号
	public static ServerAddress worldServer = null;
	public static Map<String, ServerAddress> gameServerMap = null;
	public static Map<String, ServerAddress> battleServerMap = null;

	// 数据库服务器配置
	/** 数据库地址 */
	public static ServerAddress dbAddress = null;
	/** 数据路类型 默认0=mongodb */
	public static DBType dbType;
	/** 数据库名称 */
	public static String dbName = null;
	/** 数据库连接数 */
	public static short dbConnectionNum;
	/** 数据库用户验证信息 */
	public static boolean dbNeedAuth = true;
	public static String dbUserName = null;
	public static String dbPassword = null;

	// redis服务器配置
	public static String redisAddres = null;
	public static int redisPort;
	public static int redisTimeOut;
	public static int poolMaxActive;
	public static int poolMaxIdle;
	public static int poolMaxWait;
	public static String poolTestOnBorrow;

	// 日志数据库服务器配置
	public static boolean logDBUsed = true;
	public static ServerAddress logDBAddress = null;
	public static DBType logDBType;
	public static String logDBName = null;
	public static short logDBConnectionNum;
	public static boolean logDBNeedAuth = true;
	public static String logDBUserName = null;
	public static String logDBPassword = null;

	// 前端静态资源路径
	private String webUrl = null;
	public static String flashConfigUrl = null;
	public static String flashMapConfigUrl = null;

	public void init() {
		readPropertiesFile();
		initServerProperties();
		initDBProperties();
		initLogDbProperties();
		loadServerAddress();
		initWebUrl();
		initRedis();
	}

	public void initRedis() {
		try {
			if (redisAddres == null) {
				properties = new Properties();
				InputStream inputStream = ClassLoader.getSystemResourceAsStream(PROPERTY_FILE_PATH);
				properties.load(inputStream);
				redisAddres = (String) properties.getProperty("redis_ip");
				redisPort = Integer.valueOf(properties.getProperty("redis_port"));
				redisTimeOut = Integer.valueOf(properties.getProperty("redis_timeout"));
				poolMaxActive = Integer.valueOf(properties.getProperty("poolMaxActive"));
				poolMaxIdle = Integer.valueOf(properties.getProperty("poolMaxIdle"));
				poolMaxWait = Integer.valueOf(properties.getProperty("poolMaxWait"));
				poolTestOnBorrow = properties.getProperty("poolTestOnBorrow");
			}
		} catch (Exception e) {
			System.err.println("redis配置文件读取错误！");
			e.printStackTrace();
			System.exit(0);
		}

	}

	/**
	 * 读取properties文件
	 */
	private void readPropertiesFile() {
		properties = new Properties();
		protProperties = new Properties();
		try {
			InputStream inputStream = ClassLoader.getSystemResourceAsStream(PROPERTY_FILE_PATH);
			properties.load(inputStream);
			InputStream inputStream2 = ClassLoader.getSystemResourceAsStream(PORT_FILE_PATH);
			protProperties.load(inputStream2);
		} catch (Exception e) {
			logger.error("配置文件读取错误！");
			System.err.println("配置文件读取错误！");
			e.printStackTrace();
			System.exit(0);
		}
	}

	private void initWebUrl() {
		webUrl = properties.getProperty("webUrl");
		flashConfigUrl = "http://" + webUrl + properties.getProperty("flashConfigUrl");
		flashMapConfigUrl = "http://" + webUrl + properties.getProperty("flashMapConfigUrl");
	}

	/**
	 * 服务器服务的端口号
	 */
	private void initServerProperties() {
		if (protProperties.get("port") != null)
			serverPort = Short.parseShort(protProperties.get("port").toString().trim());
		if (serverPort == 0) {
			logger.error("服务器端口配置错误！");
			System.exit(0);
		}
	}

	/**
	 * 加载DB相关配置常量
	 */
	private void initDBProperties() {
		/** 数据库服务器Ip */
		String dbAddressStr = (String) properties.get("db_addr");
		if (dbAddressStr == null || dbAddressStr.length() == 0) {
			logger.error("配置的数据库Ip地址错误！");
			System.exit(0);
		}
		String[] addressArray = dbAddressStr.split(GameConstants.SPLIT_SIGN_COLON);
		dbAddress = new ServerAddress(addressArray[0], Short.parseShort(addressArray[1]), 0);

		/** 数据路类型 默认0=mongodb */
		short type = Short.parseShort((String) properties.get("db_type"));
		dbType = DBType.getDAOType(type);

		/** 数据库服务器名称 */
		dbName = (String) properties.get("db_name");
		if (dbName == null || dbName.length() == 0) {
			logger.error("配置的数据库名称错误！");
			System.exit(0);
		}

		/** 数据库连接数 */
		dbConnectionNum = Short.parseShort((String) properties.get("db_max_conn"));
		if (dbConnectionNum <= 0) {
			logger.error("配置的数据库连接数错误！");
			System.exit(0);
		}
		/** 是否验证 */
		dbNeedAuth = Short.parseShort((String) properties.get("db_is_auth")) == 1 ? true : false;

		if (dbNeedAuth) {
			/** 数据库服务器登录用户名 */
			dbUserName = (String) properties.get("db_username");
			if (dbUserName == null || dbUserName.length() == 0) {
				logger.error("配置的数据库用户名为空！");
				System.exit(0);
			}

			/** 数据库服务器登录密码 */
			dbPassword = (String) properties.get("db_password");
			if (dbPassword == null || dbPassword.length() == 0) {
				logger.error("配置的数据库密码为空！");
				System.exit(0);
			}

		}
	}

	/**
	 * 日志数据库服务器配置
	 */
	private void initLogDbProperties() {
		logDBUsed = Short.parseShort((String) properties.get("db_log_is_used")) == 1 ? true : false;
		if (logDBUsed) {
			String logDBAddressStr = (String) properties.get("db_addr_log");
			if (logDBAddressStr == null || logDBAddressStr.length() == 0) {
				logger.error("配置的日志数据库Ip地址错误！");
				System.exit(0);
			}
			String[] addressArray = logDBAddressStr.split(GameConstants.SPLIT_SIGN_COLON);
			logDBAddress = new ServerAddress(addressArray[0], Short.parseShort(addressArray[1]), 0);

			/** 数据路类型 默认0=mongodb */
			short type = Short.parseShort((String) properties.get("db_type_log"));
			logDBType = DBType.getDAOType(type);

			/** 数据库服务器名称 */
			logDBName = (String) properties.get("db_name_log");
			if (logDBName == null || logDBName.length() == 0) {
				logger.error("配置的日志数据库名称错误！");
				System.exit(0);
			}

			/** 数据库连接数 */
			logDBConnectionNum = Short.parseShort((String) properties.get("db_max_conn_log"));
			if (logDBConnectionNum <= 0) {
				logger.error("配置的日志数据库连接数错误！");
				System.exit(0);
			}
			/** 是否验证 */
			logDBNeedAuth = Short.parseShort((String) properties.get("db_is_auth_log")) == 1 ? true : false;

			if (logDBNeedAuth) {
				/** 数据库服务器登录用户名 */
				logDBUserName = (String) properties.get("db_username_log");
				if (logDBUserName == null || logDBUserName.length() == 0) {
					logger.error("配置的日志数据库用户名为空！");
					System.exit(0);
				}

				/** 数据库服务器登录密码 */
				logDBPassword = (String) properties.get("db_password_log");
				if (logDBPassword == null || logDBPassword.length() == 0) {
					logger.error("配置的日志数据库密码为空！");
					System.exit(0);
				}
			}
		}
	}

	/**
	 * 读取服务器地址
	 */
	private void loadServerAddress() {
		gameServerMap = new HashMap<String, ServerAddress>();
		battleServerMap = new HashMap<String, ServerAddress>();
		for (int i = 1; i < 30; i++) {
			String addressStr = (String) properties.get("gameServer" + i);
			if (addressStr != null && addressStr.length() > 0) {
				ServerAddress serverAddr = getServerAddress(addressStr);
				gameServerMap.put(serverAddr.getIp(), serverAddr);
			}

			addressStr = (String) properties.get("battleServer" + i);
			if (addressStr != null && addressStr.length() > 0) {
				ServerAddress serverAddr = getServerAddress(addressStr);
				battleServerMap.put(serverAddr.getIp(), serverAddr);
			}
		}

		String addressStr = (String) properties.get("worldServer");
		ServerAddress serverAddr = getServerAddress(addressStr);
		worldServer = serverAddr;
	}

	/**
	 * 分解字符串，转为ServerAddress对象
	 */
	private ServerAddress getServerAddress(String addressStr) {
		String addressArray[] = addressStr.split(GameConstants.SPLIT_SIGN_COMMA);
		String serverIp = addressArray[0].trim();
		short port = Short.parseShort(addressArray[1].trim());
		int capacity = Integer.parseInt(addressArray[2].trim());
		ServerAddress serverAddr = new ServerAddress(serverIp, port, capacity);
		return serverAddr;
	}

}
